using System;
using System.Collections.Generic;
using System.Web.UI.WebControls;

using GenericSorter = Peradigm.Framework.Domain.Collections.Generic;
using Peradigm.Framework.Domain.Collections;
using Peradigm.Framework.Persistence;
using Peradigm.Framework.Domain.Security;
using Peradigm.Framework.UI.Web;

using Liberty.Application.CaseManagement;
using Liberty.Application.GrantManagement;
using Liberty.Domain.CaseManagement;
using Liberty.Domain.GrantManagement;
using Liberty.Domain.ServiceMemberManagement;


namespace Liberty.UI.Service.CaseManagement.Controls
{
    public partial class CaseSummaryView : AbstractLibertyControl
    {
        #region Constants
        private const string
            COMMAND_SELECT_CASE = "SelectCase",
            COMMAND_ADD_GRANT = "AddGrant",
            TOTAL_AMOUNT_FORMAT = "Total Amount: {0:c}",
            SESSION_SORT_DESCRIPTION = "CaseSummarySortDescription",
            DEFAULT_SORT_PROPERTY = "DateOfInjury";
        #endregion

        #region Event Handlers
        protected void Page_Load( object sender, EventArgs e )
        {
            if( !this.IsPostBack )
            {
                this.SortDescription = new SortDescription( DEFAULT_SORT_PROPERTY );
            }           
        }

        protected void cmdAddCase_Click( object sender, EventArgs e )
        { 
            this.RaiseAddNewCaseEvent( ServiceMember );
        }

        protected void gvCaseList_Sorting( object sender, GridViewSortEventArgs e )
        {
            this.SortDescription.Property = e.SortExpression;
        }

        protected void gvCaseList_RowCommand( object sender, GridViewCommandEventArgs e )
        {
            long oid;
            switch( e.CommandName )
            {
                case COMMAND_SELECT_CASE:
                    oid = long.Parse( e.CommandArgument.ToString() );
                    this.RaiseCaseSelectedEvent( this.CaseWith( oid ) );
                    break;
                case COMMAND_ADD_GRANT:
                    oid = long.Parse( e.CommandArgument.ToString() );
                    this.RaiseAddNewGrantEvent( this.CaseWith( oid ) );
                    break;
                default:
                    break;
            }
        }
        protected void gvCaseList_PageIndexChanging( object sender, GridViewPageEventArgs e )
        {
            gvCaseList.PageIndex = e.NewPageIndex;
        }
        #endregion

        #region Methods
        public override void UpdateView()
        {
            base.UpdateView();
            gvCaseList.DataSource = this.SortedCaseList();
            gvCaseList.DataBind();
            if( this.HasCases )
            {
                lblTotalAmount.Text = String.Format( TOTAL_AMOUNT_FORMAT, this.TotalAmount() );
            }
        }
        #endregion

        #region Properties
        public event CaseSelectedEventHandler CaseSelectedListeners
        {
            add
            {
                this.CaseSelectedEvent += value;
            }
            remove
            {
                this.CaseSelectedEvent -= value;
            }
        }

        public event AddNewCaseEventHandler AddNewCaseListeners
        {
            add
            {
                this.AddNewCaseEvent += value;
            }
            remove
            {
                this.AddNewCaseEvent -= value;
            }
        }

        public event AddNewGrantEventHandler AddNewGrantListeners
        {
            add
            {
                this.AddNewGrantEvent += value;
            }
            remove
            {
                this.AddNewGrantEvent -= value;
            }
        }
        #endregion

        #region Private Methods
        private List<Case> SortedCaseList()
        {
            this.Cases.Sort( new GenericSorter.Sorter<Case>( this.SortDescription ) );
            return this.Cases;
        }

        private Case CaseWith( long oid )
        {
            return this.Cases.Find( aCase => ( aCase.Oid == oid ) );
        }

        private decimal TotalAmount()
        {
            decimal total = 0;
            this.Cases.ForEach( delegate( Case aCase )
            {
                total += aCase.TotalAmount;
            } );
            return total;
        }

        private void RaiseCaseSelectedEvent( Case aCase )
        {
            if( this.CaseSelectedEvent != null )
            {
                this.CaseSelectedEvent( aCase );
            }
        }

        private void RaiseAddNewCaseEvent(ServiceMember serviceMember)
        {
            if( this.AddNewCaseEvent != null )
            {
               
                this.AddNewCaseEvent( serviceMember );
            }
        }

        private void RaiseAddNewGrantEvent( Case aCase )
        {
            if( this.AddNewGrantEvent != null )
            {
                this.AddNewGrantEvent( aCase );
            }
        }
        #endregion

        #region Private Properties
        private SortDescription SortDescription
        {
            get
            {
                return (SortDescription)this.Session[SESSION_SORT_DESCRIPTION];
            }
            set
            {
                this.Session[SESSION_SORT_DESCRIPTION] = value;
            }
        }

        protected List<Case> Cases
        {
            get
            {
                return this.Model as List<Case>;
            }
        }

        private bool HasCases
        {
            get
            {
                return this.Cases != null && this.Cases.Count > 0;
            }
        }

        private CaseSelectedEventHandler CaseSelectedEvent
        {
            get
            {
                return i_CaseSelectedEvent;
            }
            set
            {
                i_CaseSelectedEvent = value;
            }
        }

        private AddNewCaseEventHandler AddNewCaseEvent
        {
            get
            {
                return i_AddNewCaseEvent;
            }
            set
            {
                i_AddNewCaseEvent = value;
            }
        }

        private AddNewGrantEventHandler AddNewGrantEvent
        {
            get
            {
                return i_AddNewGrantEvent;
            }
            set
            {
                i_AddNewGrantEvent = value;
            }
        }

        private ServiceMember ServiceMember
        {
            get
            {
                ServiceMemberVariable variable = new ServiceMemberVariable();
                return variable.ServiceMember;

            }
        }
        #endregion

        #region Construction and Finalization
        #endregion

        #region Data Elements
        private CaseSelectedEventHandler i_CaseSelectedEvent;
        private AddNewCaseEventHandler i_AddNewCaseEvent;
        private AddNewGrantEventHandler i_AddNewGrantEvent;
        #endregion
        
}
}
